﻿ //Copyright (C) <2013>  <jonathan cleeve norton> All Rights Reserved 
//Contact jon.norton@fin-plus.co.uk website <http://www.fin-plus.co.uk/>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Data;
using System.Windows.Controls.DataVisualization.Charting;
using FinPlusAssembler;
using FinPlusInterfaces;

namespace FinPlusCompView
{
    public partial class FinPlusGapCashChart : FinPlusControl
    {
        [State(Test = true)]
        public override bool IsValid { get; set; }
        [State(Save = true, Test = true)]
        public override string TestString { get { return Adapter.ToString(); } }
        [State(Test = true)]
        public int ChildrenCount { get { return stackPanel.Children.Count; } }
        public override IPods Adapter { get { return _conn.Adapter; } }

        private enum DockControls { FinPlusConnectService, Exception, Default }
        private IDPods _pods;
        private FinPlusConnectService _conn;

        //construct
        public FinPlusGapCashChart(IFinPlusComp connection)
        {
            InitializeComponent();
            _conn = (FinPlusConnectService)connection;
            _pods = _conn.DPods();
            IsValid = true;
            AddCharts();
        }

        //common control interface
        public override void Dispose()
        {
            try
            {
                if(_conn !=null)
                    _conn.Dispose();
            }
            catch (Exception e)
            {
                Level.Error.Log(Id, Config, e.Message, e);
            }
        }

        //public
        public void AddChart(IDPod dPod)
        {
            try
            {
                Chart chart = new Chart() { Style = (Style)FindResource("chartStyle") };
                chart.Title = dPod.GetValue("Instrument");

                var block = GetLineBlockSeries(dPod.DateSeries());

                var lng = new AreaSeries()
                {
                    DependentValueBinding = new Binding("Value"),
                    IndependentValueBinding = new Binding("Key"),
                    DataPointStyle = (Style)FindResource("lineAreaDataPointStyleLong"),
                    ItemsSource = block.Where(v => v.Value >= 0).ToDictionary(v => v.Key, v => v.Value)
                };

                var sht = new AreaSeries()
                {
                    DependentValueBinding = new Binding("Value"),
                    IndependentValueBinding = new Binding("Key"),
                    DataPointStyle = (Style)FindResource("lineAreaDataPointStyleShort"),
                    ItemsSource = block.Where(v => v.Value <= 0).ToDictionary(v => v.Key, v => v.Value)
                };

                var x = new DateTimeAxis() { Interval = 1, Orientation = AxisOrientation.X, AxisLabelStyle = (Style)FindResource("axisLabelStyleDate"), IntervalType = DateTimeIntervalType.Months };
                var y = new LinearAxis() { Orientation = AxisOrientation.Y, ShowGridLines = true, AxisLabelStyle = (Style)FindResource("axisLabelStyleNum") };

                chart.Axes.Add(x);
                chart.Axes.Add(y);
                chart.Series.Add(lng);
                chart.Series.Add(sht);

                stackPanel.Children.Add(chart);
            }
            catch (Exception e)
            {
                IsValid = Level.Error.Log(Id, Config, e.Message, e);
            }
        }

        //private
        private void AddCharts()
        {
            foreach (var pod in _pods)
                AddChart(pod);
        }

        private IDictionary<DateTime, double> GetLineBlockSeries(IDictionary<DateTime, object> series)
        {
            try
            {
                DateTime last = DateTime.MinValue;
                double lastTotal = 0;

                var block = new Dictionary<DateTime, double>();
                foreach (var kvp in series)
                {
                    var currTotal = (double)kvp.Value/1000000;
                    if (last != DateTime.MinValue)
                    {
                        block.Add(last, lastTotal);
                        block.Add(kvp.Key.AddMilliseconds(-2), lastTotal);
                        if ((lastTotal > 0 && currTotal < 0) || (lastTotal < 0 && currTotal > 0)) //x zero then add 0
                            block.Add(kvp.Key.AddMilliseconds(-1), 0);
                    }
                    last = kvp.Key;
                    lastTotal = currTotal;
                }
                block.Add(last, lastTotal);
                return block;
            }
            catch
            {
                throw;
            }
        }
    }
}
